// Stereo matching Testing System Beta1 
// Author: Qiaosong Wang, CIS Department, University of Delaware
// http://qiaosong.co.nr

#include "stdafx.h"
#include "mymfc.h"
#include "mymfcDlg.h"
//////////////
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <math.h>
#include <ctime>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
//Global Variables
CString LeftPath;
CString RightPath;
CString SavePath;
IplImage *saveresult; 
CEdit *wEdit3,*wEdit4,*wEdit1,*wEdit2;
int globalwindowsize=9,globaldsr=20,globalwidth=640,globalheight=480;
// CAboutDlg dialog used for App About



class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

	// Dialog Data
	enum { IDD = IDD_ABOUTBOX };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

	// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CmymfcDlg dialog




CmymfcDlg::CmymfcDlg(CWnd* pParent /*=NULL*/)
: CDialog(CmymfcDlg::IDD, pParent)
, LeftinputImage(NULL),RightinputImage(NULL)
, windowsize(0)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CmymfcDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//DDX_Control(pDX, IDC_EDIT2, windowsize);
}

BEGIN_MESSAGE_MAP(CmymfcDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_ReadImg, &CmymfcDlg::OnBnClickedReadimg)
	ON_BN_CLICKED(IDC_NCCmatch, &CmymfcDlg::OnBnClickedNCCmatch)
	ON_BN_CLICKED(IDC_ReadImg2, &CmymfcDlg::OnBnClickedReadimg2)


	ON_BN_CLICKED(IDC_SADmatch, &CmymfcDlg::OnBnClickedSadmatch)
	ON_BN_CLICKED(IDC_SSDmatch, &CmymfcDlg::OnBnClickedSsdmatch)
	ON_BN_CLICKED(IDC_SADBM, &CmymfcDlg::OnBnClickedSadbm)
	ON_BN_CLICKED(IDC_SGBM, &CmymfcDlg::OnBnClickedSgbm)
	ON_BN_CLICKED(IDC_GC, &CmymfcDlg::OnBnClickedGc)

	ON_BN_CLICKED(IDC_BUTTON3, &CmymfcDlg::OnBnClickedButton3)
	//ON_EN_CHANGE(IDC_EDIT2, &CmymfcDlg::OnEnChangeEdit2)

	ON_BN_CLICKED(IDC_BUTTON4, &CmymfcDlg::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_Anag, &CmymfcDlg::OnBnClickedAnag)
	ON_BN_CLICKED(IDC_BUTTON6, &CmymfcDlg::OnBnClickedButton6)
	ON_BN_CLICKED(IDC_BUTTON7, &CmymfcDlg::OnBnClickedButton7)
	ON_BN_CLICKED(IDC_BUTTON8, &CmymfcDlg::OnBnClickedButton8)
END_MESSAGE_MAP()


// CmymfcDlg message handlers

BOOL CmymfcDlg::OnInitDialog()
{ GetDlgItem(IDC_output)-> SetWindowText("Program only works correctly with a resolution of more than 1280*720! \n Copyright(C)2011 Qiaosong Wang\n Computer and Information Sciences\n Univewrsity of Delaware\n http:/qiaosong.co.nr");
wEdit3=(CEdit*) GetDlgItem(IDC_EDIT3);
wEdit4=(CEdit*) GetDlgItem(IDC_EDIT4);
wEdit3->SetWindowText("9");
wEdit4->SetWindowText("20");
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
	CString strAboutMenu;
	strAboutMenu.LoadString(IDS_ABOUTBOX);
	if (!strAboutMenu.IsEmpty())
	{
		pSysMenu->AppendMenu(MF_SEPARATOR);
		pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
	}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);			// Set big icon
SetIcon(m_hIcon, FALSE);		// Set small icon

// TODO: Add extra initialization here
CvSize ImgSize;
ImgSize.height = IMAGE_HEIGHT;
ImgSize.width = IMAGE_WIDTH;
LeftinputImage = cvCreateImage( ImgSize, IPL_DEPTH_8U, IMAGE_CHANNELS );
RightinputImage = cvCreateImage( ImgSize, IPL_DEPTH_8U, IMAGE_CHANNELS );
return TRUE;  // return TRUE  unless you set the focus to a control
}

void CmymfcDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CmymfcDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();						// Repaint dialog
		CDialog::UpdateWindow();				// Update window
		ShowImage( LeftinputImage, IDC_ShowImg );	
		ShowImage( RightinputImage, IDC_ShowImg2 );
		ShowImage( saveresult, IDC_ShowImg3 );//Repaint
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CmymfcDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}








////////////Stereo matching///////////////////
template <class T> class Image
{
private:
	IplImage *imgp;
public:
	Image(IplImage *img = 0)
	{
		imgp = img;
	}
	~Image()
	{
		imgp = 0;
	}
	void operator = (IplImage *img)
	{
		imgp = img;
	}
	inline T *operator[](const int rowIndx)
	{
		return ((T*)(imgp->imageData + rowIndx * imgp->widthStep));
	}

};

typedef struct
{
	unsigned char b, g, r;
} RgbPixel;

typedef struct
{
	float b, g, r;
} RgbPixelFloat;

typedef Image < RgbPixel > RgbImage;
typedef Image < RgbPixelFloat > RgbImageFloat;
typedef Image < unsigned char > BwImage;
typedef Image < float > BwImageFloat;



void displayImageProperty(IplImage *image)
{
	cout << "-------Image Properties--------" << endl;
	cout << "Image width=" << image->width << endl;
	cout << "Image height=" << image->height << endl;
	cout << "Image depth=" << image->depth << endl;
	cout << "Image nSize=" << image->nSize << endl;
	cout << "Image nChannels=" << image->nChannels << endl;
	char *origin;
	char *dataOrder;
	if (image->origin == 0)
	{
		origin = "Top-left";
	}
	else
	{
		origin = "Below-left"; //image->origin=1
	}
	cout << "Image origin=" << origin << endl;

	if (image->dataOrder == 0)
	{
		dataOrder = "Order_Pixel(Interleaved)";
	}
	else
	{
		dataOrder = "Order_Plane"; //image->dataOrder=1
	}
	cout << "Image dataOrder=" << dataOrder << endl;
	cout << "Image widthStep=" << image->widthStep << " Bytes" << endl;

}

//display an image in a new window with title to be given.
void displayImageNewWindow(char *title, CvArr *img)
{
	cvNamedWindow(title, CV_WINDOW_AUTOSIZE);
	cvShowImage(title, img);
}

int getMaxMin(double value[], int valueSize, int maxmin)
{
	int pos = 0;
	int i = 0;
	double max1 =  - 1; //?-999999;
	double min1 = 999999;

	if (maxmin == 1)
	{
		//find max
		for (i = 0; i < valueSize; i++)
		{
			//find the index with the max ncc; 
			if (value[i] > max1)
			{
				pos = i;
				max1 = value[i];
			}
		}
	}

	if (maxmin == 0)
	{
		//find min
		for (i = 0; i < valueSize; i++)
		{
			//find the index with the max ncc; 
			if (value[i] < min1)
			{
				pos = i;
				min1 = value[i];
			}
		}
	}

	return pos;
}

//NCC begins
IplImage *generateDisparityImageusingNCC(IplImage *LeftinputImage32, IplImage
										 *RightinputImage32, int windowSize, int DSR)
{

	int offset = floor((double)windowSize / 2);
	int height = LeftinputImage32->height;
	int width = LeftinputImage32->width;
	double *localNCC = new double[DSR];

	int x = 0, y = 0, d = 0, m = 0;
	int N = windowSize;

	IplImage *leftWinImg = cvCreateImage(cvSize(N, N), 32, 1); 
	//mySubImage(LeftinputImage32,cvRect(0,0,N,N));
	IplImage *rightWinImg = cvCreateImage(cvSize(N, N), 32, 1);
	; //mySubImage(RightinputImage32,cvRect(0,0,N,N));
	IplImage *disparity = cvCreateImage(cvSize(width, height), 8, 1); 
	//or IPL_DEPTH_8U
	BwImage imgA(disparity);

	for (y = 0; y < height; y++)
	{
		for (x = 0; x < width; x++)
		{
			imgA[y][x] = 0;
		}
	}

	CvScalar s1;
	CvScalar s2;
	for (y = 0; y < height - N; y++)
	{
		//height-N
		for (x = 0; x < width - N; x++)
		{
			//width-N
			//getWindow(i,j,leftim,wl,N);
			cvSetImageROI(LeftinputImage32, cvRect(x, y, N, N));
			s1 = cvAvg(LeftinputImage32, NULL);
			cvSubS(LeftinputImage32, s1, leftWinImg, NULL); //zero-means
			cvNormalize(leftWinImg, leftWinImg, 1, 0, CV_L2, NULL);
			d = 0;

			//initialise localNCC
			for (m = 0; m < DSR; m++)
			{
				localNCC[m] = 0;
			}

			do
			{
				if (x - d >= 0)
				{

					cvSetImageROI(RightinputImage32, cvRect(x - d, y, N, N));
					s2 = cvAvg(RightinputImage32, NULL);
					cvSubS(RightinputImage32, s2, rightWinImg, NULL); //zero-means 
					cvNormalize(rightWinImg, rightWinImg, 1, 0, CV_L2, NULL);
				}
				else
				{
					break;
				}
				localNCC[d] = cvDotProduct(leftWinImg, rightWinImg);
				cvResetImageROI(RightinputImage32);
				d++;
			}
			while (d <= DSR);

			//to find the best d and store
			imgA[y + offset][x + offset] = getMaxMin(localNCC, DSR, 1) *16;
			cvResetImageROI(LeftinputImage32);
		} //x 
		if (y % 10 == 0)
			cout << "row=" << y << " of " << height << endl;
	} //y

	cvReleaseImage(&leftWinImg);
	cvReleaseImage(&rightWinImg);

	return disparity;

}
////NCC ENDS///////////

////SAD BEGINS//////////
IplImage* generateDisparityImageusingSAD(IplImage* greyLeftImg32,
										 IplImage* greyRightImg32, 
										 int windowSize,int DSR){

											 int offset=floor((double)windowSize/2); 
											 int height=greyLeftImg32->height;
											 int width=greyLeftImg32->width;
											 double* localSAD=new double[DSR];

											 int x=0, y=0,d=0,m=0;
											 int N=windowSize;             

											 IplImage* winImg=cvCreateImage(cvSize(N,N),32,1);//mySubImage(greyLeftImg32,cvRect(0,0,N,N));

											 IplImage* disparity=cvCreateImage(cvSize(width,height),8,1);//or IPL_DEPTH_8U
											 BwImage imgA(disparity);

											 for (y=0;y<height;y++){ 
												 for (x=0;x<width;x++){
													 imgA[y][x]=0;
												 }
											 }

											 CvScalar sum;
											 //CvScalar s2;
											 for (y=0;y<height-N;y++){ //height-N
												 for (x=0;x<width-N;x++){//width-N 
													 cvSetImageROI(greyLeftImg32, cvRect(x,y,N,N));
													 d=0;         
													 //initialise localSAD
													 for (m=0;m<DSR;m++){localSAD[m]=0;} 

													 //start matching
													 do{ 
														 if (x-d>=0){ 
															 cvSetImageROI(greyRightImg32, cvRect(x-d,y,N,N)); 
														 }else{
															 break;
														 } 

														 cvAbsDiff(greyLeftImg32,greyRightImg32,winImg);//absolute difference
														 sum=cvSum(winImg);//sum
														 localSAD[d]=sum.val[0];//0 means single channel

														 cvResetImageROI(greyRightImg32); 
														 d++;
													 }while(d<=DSR);

													 //to find the best d and store
													 imgA[y+offset][x+offset]=getMaxMin(localSAD,DSR,0)*16; //0 means return minimum index
													 cvResetImageROI(greyLeftImg32);
												 }//x 
												 if (y%10==0)cout<<"row="<<y<<" of "<<height<<endl;  
											 }//y

											 cvReleaseImage(&winImg); 
											 //cvReleaseImage(&rightWinImg); 

											 return disparity;

}
////SAD ENDS////////////

////SSD STARTS//////////
IplImage* generateDisparityImageusingSSD(IplImage* greyLeftImg32,
										 IplImage* greyRightImg32, 
										 int windowSize,int DSR){

											 int offset=floor((double)windowSize/2); 
											 int height=greyLeftImg32->height;
											 int width=greyLeftImg32->width;
											 double* localSAD=new double[DSR];

											 int x=0, y=0,d=0,m=0;
											 int N=windowSize;             

											 IplImage* winImg=cvCreateImage(cvSize(N,N),32,1);//mySubImage(greyLeftImg32,cvRect(0,0,N,N));

											 IplImage* disparity=cvCreateImage(cvSize(width,height),8,1);//or IPL_DEPTH_8U
											 BwImage imgA(disparity);

											 for (y=0;y<height;y++){ 
												 for (x=0;x<width;x++){
													 imgA[y][x]=0;
												 }
											 }

											 CvScalar sum;
											 //CvScalar s2;
											 for (y=0;y<height-N;y++){ //height-N
												 for (x=0;x<width-N;x++){//width-N 
													 cvSetImageROI(greyLeftImg32, cvRect(x,y,N,N));
													 d=0;         
													 //initialise localSAD
													 for (m=0;m<DSR;m++){localSAD[m]=0;} 

													 //start matching
													 do{ 
														 if (x-d>=0){ 
															 cvSetImageROI(greyRightImg32, cvRect(x-d,y,N,N)); 
														 }else{
															 break;
														 } 

														 cvAbsDiff(greyLeftImg32,greyRightImg32,winImg);//absolute difference
														 sum=cvSum(winImg);//sum
														 for(int i=1;i<4;i++)
														 {sum.val[i]=sum.val[i]*sum.val[i];}
														 localSAD[d]=sum.val[0]*sum.val[0];//0 means single channel

														 cvResetImageROI(greyRightImg32); 
														 d++;
													 }while(d<=DSR);

													 //to find the best d and store
													 imgA[y+offset][x+offset]=getMaxMin(localSAD,DSR,0)*16; //0 means return minimum index
													 cvResetImageROI(greyLeftImg32);
												 }//x 
												 if (y%10==0)cout<<"row="<<y<<" of "<<height<<endl;  
											 }//y

											 cvReleaseImage(&winImg); 
											 //cvReleaseImage(&rightWinImg); 

											 return disparity;

}
////SSD ENDS////////////

////////////Stereo matching///////////////////






void CmymfcDlg::OnBnClickedReadimg()
{
	// TODO: Add your control notification handler code here
	CFileDialog dlg(
		TRUE, _T("*.bmp"), NULL,
		OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
		_T("image files (*.bmp; *.jpg;*.png;*.tiff*.ppm) |*.bmp; *.jpg;*.png;*.tiff*.ppm | All Files (*.*) |*.*||"), NULL
		);										// Type selection
	dlg.m_ofn.lpstrTitle = _T("Open Image");
	if( dlg.DoModal() != IDOK )					
		return;

	LeftPath = dlg.GetPathName();			// Get picture position

	IplImage* ipl = cvLoadImage( LeftPath, 1 );	// Buffer to a variable IplImage* ipl 
	if( !ipl )									// Judge if read the picture successfully
		return;
	if( LeftinputImage )								// Set Zero
		cvZero( LeftinputImage );

	ResizeImage( ipl );	
	ShowImage( LeftinputImage, IDC_ShowImg );			
	cvReleaseImage( &ipl );						// Release ipl
}

void CmymfcDlg::ShowImage( IplImage* img, UINT ID )	
{
	CDC* pDC = GetDlgItem( ID ) ->GetDC();		// Get DC
	HDC hDC = pDC ->GetSafeHdc();				// Get HDC for drawing

	CRect rect;
	GetDlgItem(ID) ->GetClientRect( &rect );
	int rw = rect.right - rect.left;			
	int rh = rect.bottom - rect.top;
	int iw = img->width;				
	int ih = img->height;
	int tx = (int)(rw - iw)/2;					// Set pic to the center
	int ty = (int)(rh - ih)/2;
	SetRect( rect, tx, ty, tx+iw, ty+ih );

	CvvImage cimg;
	cimg.CopyOf( img );							
	cimg.DrawToHDC( hDC, &rect );				

	ReleaseDC( pDC );
}

void CmymfcDlg::OnBnClickedNCCmatch()
{ 
	GetDlgItem(IDC_output)-> SetWindowText("NCC matching begins! \n Very slow matching algorithm, please wait patiently until the result is returned to you."); 
	IplImage *LeftinputImage= cvLoadImage(LeftPath, 0);
	IplImage *RightinputImage = cvLoadImage(RightPath, 0);

	int width = LeftinputImage->width;
	int height = LeftinputImage->height;

	/****************8U to 32F**********************/
	IplImage *LeftinputImage32 = cvCreateImage(cvSize(width, height), 32, 1); 
	//IPL_DEPTH_32F
	IplImage *RightinputImage32 = cvCreateImage(cvSize(width, height), 32, 1);
	cvConvertScale(LeftinputImage, LeftinputImage32, 1 / 255.);
	cvConvertScale(RightinputImage, RightinputImage32, 1 / 255.); 
	//1/255. equals to 1/255.0 

	//-------------Computing stereo matching---------------- 
	int windowSize = globalwindowsize, DSR = globaldsr; //Disparity Search Range
	saveresult = generateDisparityImageusingNCC(LeftinputImage32, RightinputImage32,
		windowSize, DSR);



	//cvSaveImage("D:/OpenCV_stuff/SampleImages/disparity.jpg",disparity32);
	ShowImage( saveresult, IDC_ShowImg3 );	
	CDialog::UpdateWindow();

	GetDlgItem(IDC_output)-> SetWindowText("NCC matching finished, result returned"); 

	//********destroy window************/

	cvReleaseImage(&LeftinputImage32);
	cvReleaseImage(&RightinputImage32);
	cvReleaseImage(&LeftinputImage);
	cvReleaseImage(&RightinputImage);




}

void CmymfcDlg::ResizeImage(IplImage* img)
{

	int w = img->width;
	int h = img->height;
	int max = (w > h)? w: h;
	float scale = (float) ( (float) max / 256.0f );
	int nw = (int)( w/scale );
	int nh = (int)( h/scale );
	int tlx = (nw > nh)? 0: (int)(256-nw)/2;
	int tly = (nw > nh)? (int)(256-nh)/2: 0;

	// Set ROI of LeftinputImage 
	cvSetImageROI( LeftinputImage, cvRect( tlx, tly, nw, nh) );
	cvSetImageROI( RightinputImage, cvRect( tlx, tly, nw, nh) );
	cvResize( img, LeftinputImage );
	cvResize( img, RightinputImage );
    // Reset and prepare for reading next image
	cvResetImageROI( LeftinputImage );
	cvResetImageROI( RightinputImage );
}

void CmymfcDlg::OnBnClickedReadimg2()
{
	// TODO: Add your control notification handler code here
	CFileDialog dlg(
		TRUE, _T("*.bmp"), NULL,
		OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
		_T("image files (*.bmp; *.jpg;*.png;*.tiff*.ppm) |*.bmp; *.jpg;*.png;*.tiff*.ppm | All Files (*.*) |*.*||"), NULL
		);									
	dlg.m_ofn.lpstrTitle = _T("Open Image");	
	if( dlg.DoModal() != IDOK )					
		return;

	RightPath = dlg.GetPathName();			

	IplImage* ipl = cvLoadImage( RightPath, 1 );	
	if( !ipl )									
		return;
	if( RightinputImage )								
		cvZero( RightinputImage );

	ResizeImage( ipl );	
	ShowImage( RightinputImage, IDC_ShowImg2 );			
	cvReleaseImage( &ipl );					
}





void CmymfcDlg::OnBnClickedSadmatch()
{
	GetDlgItem(IDC_output)-> SetWindowText("SAD matching begins!\n Very slow matching algorithm, please wait patiently until the result is returned to you."); 
	IplImage *LeftinputImage= cvLoadImage(LeftPath, 0);
	IplImage *RightinputImage = cvLoadImage(RightPath, 0);

	int width = LeftinputImage->width;
	int height = LeftinputImage->height;

	/****************8U to 32F**********************/
	IplImage *LeftinputImage32 = cvCreateImage(cvSize(width, height), 32, 1); 
	//IPL_DEPTH_32F
	IplImage *RightinputImage32 = cvCreateImage(cvSize(width, height), 32, 1);
	cvConvertScale(LeftinputImage, LeftinputImage32, 1 / 255.);
	cvConvertScale(RightinputImage, RightinputImage32, 1 / 255.); 
	//1/255. equals to 1/255.0 

	//-------------Computing stereo matching---------------- 
	int windowSize =globalwindowsize, DSR = globaldsr; //Disparity Search Range
	saveresult = generateDisparityImageusingSAD(LeftinputImage32, RightinputImage32,
		windowSize, DSR);


	//cvSaveImage("D:/OpenCV_stuff/SampleImages/disparity.jpg",disparity32);
	ShowImage( saveresult, IDC_ShowImg3 );	
	CDialog::UpdateWindow();
	GetDlgItem(IDC_output)-> SetWindowText("SAD matching finished, result returned"); 

	//********destroy window************/

	cvReleaseImage(&LeftinputImage32);
	cvReleaseImage(&RightinputImage32);
	cvReleaseImage(&LeftinputImage);
	cvReleaseImage(&RightinputImage);

}

void CmymfcDlg::OnBnClickedSsdmatch()
{
	GetDlgItem(IDC_output)-> SetWindowText("SSD matching begins!\n Quite slow matching algorithm, please wait patiently until the result is returned to you."); 
	IplImage *LeftinputImage= cvLoadImage(LeftPath, 0);
	IplImage *RightinputImage = cvLoadImage(RightPath, 0);

	int width = LeftinputImage->width;
	int height = LeftinputImage->height;

	/****************8U to 32F**********************/
	IplImage *LeftinputImage32 = cvCreateImage(cvSize(width, height), 32, 1); 
	//IPL_DEPTH_32F
	IplImage *RightinputImage32 = cvCreateImage(cvSize(width, height), 32, 1);
	cvConvertScale(LeftinputImage, LeftinputImage32, 1 / 255.);
	cvConvertScale(RightinputImage, RightinputImage32, 1 / 255.); 
	//1/255. equals to 1/255.0 

	//-------------Computing stereo matching---------------- 
	int windowSize = globalwindowsize, DSR = globaldsr; //Disparity Search Range
	saveresult = generateDisparityImageusingSSD(LeftinputImage32, RightinputImage32,
		windowSize, DSR);


	//cvSaveImage("D:/OpenCV_stuff/SampleImages/disparity.jpg",disparity32);
	ShowImage( saveresult, IDC_ShowImg3 );	
	CDialog::UpdateWindow();
	GetDlgItem(IDC_output)-> SetWindowText("SSD matching finished, result returned"); 

	//********destroy window************/

	cvReleaseImage(&LeftinputImage32);
	cvReleaseImage(&RightinputImage32);
	cvReleaseImage(&LeftinputImage);
	cvReleaseImage(&RightinputImage);

}

void CmymfcDlg::OnBnClickedSadbm()
{   GetDlgItem(IDC_output)-> SetWindowText("Improved SAD Block Matching begins!"); 
IplImage *LeftinputImage= cvLoadImage(LeftPath, 0);
IplImage *RightinputImage = cvLoadImage(RightPath, 0);
CvSize imageSize=cvGetSize(LeftinputImage);
CvMat* disparity=cvCreateMat(imageSize.height,imageSize.width,CV_32FC1);
CvMat* norm_disparity=cvCreateMat(imageSize.height,imageSize.width,CV_8U);  
CvStereoBMState *BMState = cvCreateStereoBMState();  
int SADWindowSize=globalwindowsize;   
BMState->SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 9;  
BMState->minDisparity = 0;  
BMState->numberOfDisparities = 32;  
BMState->textureThreshold = 10;  
BMState->uniquenessRatio = 15;  
BMState->speckleWindowSize = 100;  
BMState->speckleRange = 32;  
BMState->disp12MaxDiff = 1;  
cvFindStereoCorrespondenceBM(LeftinputImage,RightinputImage,disparity,BMState);
cvNormalize(disparity,norm_disparity,0,256,CV_MINMAX);
IplImage* temp = cvCreateImage(cvGetSize(norm_disparity),8,1);
cvGetImage(norm_disparity,temp);
ShowImage( temp, IDC_ShowImg3 );
CDialog::UpdateWindow();
GetDlgItem(IDC_output)-> SetWindowText("Improved SAD Block Matching finished, result returned"); 

cvReleaseImage(&LeftinputImage);
cvReleaseImage(&RightinputImage);
cvReleaseStereoBMState(&BMState);
cvReleaseMat(&disparity);
cvReleaseMat(&norm_disparity);
}

void CmymfcDlg::OnBnClickedSgbm()
{  IplImage *LeftinputImage= cvLoadImage(LeftPath, 0);
IplImage *RightinputImage = cvLoadImage(RightPath, 0);
GetDlgItem(IDC_output)-> SetWindowText("Semi-global Block Matching begins!"); 
cv::StereoSGBM sgbm;

int SADWindowSize=globalwindowsize;
sgbm.preFilterCap = 63;
sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3;

int cn = LeftinputImage->nChannels;
int numberOfDisparities=64;

sgbm.P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
sgbm.P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
sgbm.minDisparity = 0;
sgbm.numberOfDisparities = numberOfDisparities;
sgbm.uniquenessRatio = 10;
sgbm.speckleWindowSize = 100;
sgbm.speckleRange = 32;
sgbm.disp12MaxDiff = 1;

cv::Mat disp, disp8;


sgbm(LeftinputImage,RightinputImage, disp);


disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.));
IplImage disp8old = disp8;
IplImage* dispout = cvCreateImage(cvSize(disp8old.width,disp8old.height),IPL_DEPTH_8U,3);  //memory leak
cvConvertImage(&disp8old, dispout, CV_CVTIMG_SWAP_RB);  
saveresult=dispout;


ShowImage(dispout, IDC_ShowImg3 );	

GetDlgItem(IDC_output)-> SetWindowText("Semi-global Block Matching finished, result returned. It's fast isn't it?"); 

cvReleaseImage(&LeftinputImage);
cvReleaseImage(&RightinputImage);

}

void CmymfcDlg::OnBnClickedGc()
{ GetDlgItem(IDC_output)-> SetWindowText("GC matching begins! \n Another slow matching algorithm, please wait patiently until the result is returned to you.");
IplImage *LeftinputImage= cvLoadImage(LeftPath, 0);
IplImage *RightinputImage = cvLoadImage(RightPath, 0);
CvStereoGCState* GCState=cvCreateStereoGCState(64,3);
assert(GCState);
CvMat* gcdispleft=cvCreateMat(LeftinputImage->height,LeftinputImage->width,CV_16S);
CvMat* gcdispright=cvCreateMat(RightinputImage->height,RightinputImage->width,CV_16S);
CvMat* gcvdisp=cvCreateMat(LeftinputImage->height,LeftinputImage->width,CV_8U);
cvFindStereoCorrespondenceGC(LeftinputImage,RightinputImage,gcdispleft,gcdispright,GCState);
cvNormalize(gcdispleft,gcvdisp,0,255,CV_MINMAX);
cvNormalize(gcdispright,gcvdisp,0,255,CV_MINMAX);
IplImage* temp = cvCreateImage(cvGetSize(gcvdisp),8,1);
cvGetImage(gcvdisp,temp);
ShowImage( temp, IDC_ShowImg3 );	
saveresult=temp;
GetDlgItem(IDC_output)-> SetWindowText("GC result returned!");

cvReleaseMat(&gcdispleft);
cvReleaseMat(&gcdispright);
cvReleaseMat(&gcvdisp);
}



void CmymfcDlg::OnBnClickedButton3()
{
	globalwindowsize=GetDlgItemInt(IDC_EDIT3);
	globaldsr=GetDlgItemInt(IDC_EDIT4);
	globalwidth=GetDlgItemInt(IDC_EDIT1);
	globalheight=GetDlgItemInt(IDC_EDIT2);
	GetDlgItem(IDC_output)-> SetWindowText("New parameters set!");
}




void CmymfcDlg::OnBnClickedButton4()
{
	CString filename;
	TCHAR szFilters[] = _T("All Picture File(*.bmp,*.jpeg,*.jpg,*.gif,*.tiff)");
	CFileDialog dlg(FALSE,_T(""), _T("*.*"),OFN_FILEMUSTEXIST,szFilters);

	if (dlg.DoModal () == IDOK)
	{
		filename = dlg.GetPathName();
	}
	else
		return;

	cvSaveImage(filename, saveresult);
}

void CmymfcDlg::OnBnClickedAnag()
{
	IplImage *imageLeft= cvLoadImage(LeftPath, 0);
	IplImage *imageRight = cvLoadImage(RightPath, 0);

	int resultWidth = imageLeft->width;
	int resultHeight = imageLeft->height;
	IplImage *imageResult;
	imageResult = cvCreateImage(cvSize(resultWidth,resultHeight),IPL_DEPTH_8U,3);//IPL_DEPTH_8U

	for(int i=0;i<resultWidth;i++)
	{
		for(int j=0;j<resultHeight;j++)
		{
			int B=((uchar *)(imageRight->imageData + j*imageRight->widthStep))[i*imageRight->nChannels + 0];
			int G=((uchar *)(imageRight->imageData + j*imageRight->widthStep))[i*imageRight->nChannels + 1];
			int R=((uchar *)(imageLeft->imageData + j*imageLeft->widthStep))[i*imageLeft->nChannels + 2];

			((uchar *)(imageResult->imageData + j*imageResult->widthStep))[i*imageResult->nChannels + 0]=B;
			((uchar *)(imageResult->imageData + j*imageResult->widthStep))[i*imageResult->nChannels + 1]=G;
			((uchar *)(imageResult->imageData + j*imageResult->widthStep))[i*imageResult->nChannels + 2]=R;
		}
	}
	ShowImage( imageResult, IDC_ShowImg3 );	
	saveresult=imageResult;
}

void CmymfcDlg::OnBnClickedButton6()
{
	IplImage* pImg=0; 
	pImg = saveresult;
	cvSmooth(pImg,pImg,CV_MEDIAN,3,0,0,0);
	ShowImage(pImg, IDC_ShowImg3 );	
	GetDlgItem(IDC_output)-> SetWindowText("median filter applyed!");
}

void CmymfcDlg::OnBnClickedButton7()
{
	IplImage* pImg=0; 
	pImg = saveresult;
	cvSmooth(pImg,pImg,CV_GAUSSIAN,3,0,0,0);
	ShowImage(pImg, IDC_ShowImg3 );	
	GetDlgItem(IDC_output)-> SetWindowText("mean filter applyed!");
}

void CmymfcDlg::OnBnClickedButton8()
{
	IplImage *img=0;
	img=saveresult;

	// Perform histogram equalization
	cvEqualizeHist( img, img );
	ShowImage(img, IDC_ShowImg3 );	
	GetDlgItem(IDC_output)-> SetWindowText("Histogram equalization applyed!");

}
